package com.jabber.bot;

import java.io.IOException;

import org.apache.log4j.Logger;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smackx.muc.MultiUserChat;

import com.jabber.listeners.ChatList;
import com.jabber.listeners.RostList;
import com.jabber.readers.FleetUpReader;
import com.jabber.readers.KillboardReader;
import com.jabber.utils.BotConfig;
import com.jabber.utils.MessageUtils;

public class JabberBot {

	private static String host;
	private static int port;
	private static String user;
	private static String pass;
	private static String conferenceHost;
	private static String conferenceRoom;
	private static String conferencePass;
	private static String conferenceUser;
	private static int allianceID;
	private static String fleetUpURL;
	
	private static BotConfig config;

	private static XMPPConnection connection;
	private static MessageUtils messageUtils;
	private static ChatManager chatManager;
	private static Presence presence;
	private static Roster roster;

	private static ChatList chatListener;
	private static RostList rosterListener;
	private static MultiUserChat multiUserChat;

	private static KillboardReader kb;
	private static FleetUpReader fu;

	private static boolean exit;
	
	private static Thread kbThread;
	private static Thread fuThread;

	private static Logger logger = Logger.getLogger(JabberBot.class);

	public static void main(String[] args) {
		try {
			logger.info("Starting up...");

			init();
			connect();

			logger.info("Connected...");

			roster = connection.getRoster();
			rosterListener = new RostList();
			roster.addRosterListener(rosterListener);

			chatManager = ChatManager.getInstanceFor(connection);
			chatListener = new ChatList();
			chatManager.addChatListener(chatListener);

			logger.info("Listeners added...");

			messageUtils = new MessageUtils(config, roster, chatManager);
			
			multiUserChat = new MultiUserChat(connection, conferenceRoom + "@" + conferenceHost + "." + host);
			if (conferencePass.isEmpty()) {
				multiUserChat.join(conferenceUser);
			} else {
				multiUserChat.join(conferenceUser, conferencePass);
			}
			
			logger.info("Initializing killboard reader...");
			kb = new KillboardReader(allianceID, multiUserChat);
			kbThread = new Thread(kb);
			kbThread.start();
			
			logger.info("Initializing Fleet-Up reader...");
			fu = new FleetUpReader(fleetUpURL);
			fuThread = new Thread(fu);
			fuThread.start();
  
			while (!exit) {
				Thread.sleep(1000 * 1);
			}

			logger.info("Shutting down...");
			shutdown();
		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
	}

	private static void init() throws IOException {
		config = new BotConfig("config.properties");

		host = config.getHost();
		port = config.getPort();
		user = config.getUser();
		pass = config.getPass();
		conferenceHost = config.getConferenceHost();
		conferenceRoom = config.getConferenceChat();
		conferencePass = config.getConferencePass();
		conferenceUser = config.getConferenceUser();
		allianceID = config.getAllianceID();
		fleetUpURL = config.getFleetUpURL();
	}

	private static void connect() throws SmackException, IOException, XMPPException {
		ConnectionConfiguration config = new ConnectionConfiguration(host, port);
		config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);

		connection = new XMPPTCPConnection(config);

		connection.connect();
		connection.login(user, pass);

		presence = new Presence(Presence.Type.available);
		connection.sendPacket(presence);
	}

	private static void shutdown() throws NotConnectedException {
		kbThread.interrupt();
		fuThread.interrupt();
		multiUserChat.leave();
		roster.removeRosterListener(rosterListener);
		chatManager.removeChatListener(chatListener);
		connection.disconnect();
	}

	public static MessageUtils getMessageUtils() {
		return messageUtils;
	}
	
	public static Roster getRoster() {
		return roster;
	}

	public static void exit() {
		exit = true;
	}

}
